package com.wonderful.compose.lazy

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.Card
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.wonderful.compose.R
import com.wonderful.compose.ui.theme.ComposeLearnTheme

/**
 * Desc:
 * @Author: wonderful
 * @Time: 2024/1/17 9:55
 */
class LazyLayoutActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeLearnTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    //MainLayout()
                    //VerticalScrollable()
                    MainLayout2()
                }
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun MainLayout() {
    val state = rememberLazyListState()
    Box {
        ScrollableList(state)
        val isShowAddButton = state.firstVisibleItemIndex == 0
        AddButton(isShowAddButton)
    }
}

@Composable
fun BoxScope.AddButton(isVisible: Boolean) {
    if (isVisible) {
        FloatingActionButton(
            onClick = { /*TODO*/ },
            shape = CircleShape,
            modifier = Modifier
                .align(Alignment.BottomEnd)
                .padding(20.dp)
        ) {
            Icon(Icons.Filled.Add, "Add Button")
        }
    }
}

@Composable
fun ScrollableList(state: LazyListState) {
    val list = ('A'..'Z').map { it.toString() }

    LazyColumn(state = state) {
//        items(20) { i ->
//            Text(text = "Item $i", modifier = Modifier
//                .fillMaxWidth()
//                .height(60.dp))
//        }
        items(list) { letter ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(60.dp)
                    .padding(5.dp, 5.dp)
            ) {
                Text(
                    text = letter,
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun ScrollableRowList() {
    val list = ('A'..'Z').map { it.toString() }

    // 设置前后边距方式1（会有切割现象）
    //LazyRow(modifier = Modifier.padding(start = 5.dp, end = 5.dp)) {
    // 设置前后边距方式2
    //LazyRow(contentPadding = PaddingValues(start = 5.dp, end = 5.dp)) {
    // 设置前后边距方式3：使用Arrangement.spacedBy() 后可以不用在子元素 card 设置 Modifier.padding
    LazyRow(horizontalArrangement = Arrangement.spacedBy(5.dp)) {
//        items(list) { letter ->
//            Card(
//                modifier = Modifier
//                    .width(60.dp)
//                    .height(100.dp)
//                    .padding(5.dp, 5.dp)
//            ) {
//                Text(
//                    text = letter,
//                    textAlign = TextAlign.Center,
//                    fontSize = 20.sp,
//                    modifier = Modifier
//                        .fillMaxSize()
//                        .wrapContentHeight(Alignment.CenterVertically)
//                )
//            }
//        }

        // 带下标
        itemsIndexed(list) { index, letter ->
            Card(
                modifier = Modifier
                    .width(80.dp)
                    .height(100.dp)
                    .padding(5.dp, 5.dp)
            ) {
                Text(
                    text = "$letter $index",
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
    }
}

@Composable
fun VerticalScrollable() {
    // 嵌套滚动
    // 不同方向：左右滑动和上下滑动
    // 相同方向：需要么内层列表的高度必须是固定的
    Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
        //HorizontalScrollable()
        SubVerticalScrollable()
        for (i in 1..10) {
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(120.dp)
                    .padding(10.dp)
            ) {
                Text(
                    text = "Item $i",
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
    }
}

@Composable
fun HorizontalScrollable() {
    val list = ('A'..'Z').map { it.toString() }
    LazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
        items(list) {
            Card(
                modifier = Modifier
                    .width(100.dp)
                    .height(100.dp)
            ) {
                Text(
                    text = it,
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
    }
}

@Composable
fun SubVerticalScrollable() {
    val list = ('A'..'Z').map { it.toString() }
    LazyColumn(modifier = Modifier.height(300.dp)) {
        items(list) { letter ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(80.dp)
                    .padding(10.dp)
            ) {
                Text(
                    text = letter,
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
    }
}

//-------------------------------------------------------------------------

@Composable
fun ImageHeader() {
    Image(
        painter = painterResource(id = R.drawable.prince_christian_sound),
        contentDescription = "Header img",
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp)
    )
}

@Composable
fun ImageFooter() {
    Image(
        painter = painterResource(id = R.drawable.prince_christian_sound),
        contentDescription = "Header img",
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp)
    )
}

@Composable
fun ConcatList(state: LazyListState) {
    // 拼接不同类型的子项
    val list = (1..10).map { it.toString() }
    LazyColumn(state = state) {
        item {
            ImageHeader()
        }
        // 添加 key 参数(唯一性)，提升增删改性能
        items(list, key = { it }) { letter ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(120.dp)
                    .padding(10.dp)
            ) {
                Text(
                    text = letter,
                    textAlign = TextAlign.Center,
                    fontSize = 20.sp,
                    modifier = Modifier
                        .fillMaxSize()
                        .wrapContentHeight(Alignment.CenterVertically)
                )
            }
        }
        item {
            ImageFooter()
        }
    }
}

@Composable
fun MainLayout2() {
    val state = rememberLazyListState()
    Box {
        ConcatList(state)
        //val isShowAddButton = state.firstVisibleItemIndex == 0
        // derivedStateOf其实和mutableStateOf是比较相似的，它们都是用于创建State变量，
        // 然后Compose则会基于State变量值的变化来触发重组行为。
        // 不同的是，derivedStateOf接收的一个表达式，
        // 只有当这个表达式中的条件发生变化了，那么才算是State的值发生了变化，这时才会触发重组
        // 就很好地避免了无效重组的发生，从而也就提升了应用程序的性能
        val isShowAddButton by remember {
            derivedStateOf { state.firstVisibleItemIndex == 0 }
        }
        AddButton(isShowAddButton)
    }
}
